package org.apple.messagegenerate;

import java.util.ArrayList;
import java.util.Properties;
import java.util.Vector;

import org.apple.averager.Averager;
import org.apple.data.Position;
import org.apple.data.SensorReading;
import org.apple.navigation.NavigationDriver;
import org.apple.transmitter.Formatter;
import org.apple.transmitter.Transmitter;
import org.apple.util.Configure;

public class DefaultMessageGenrator extends Thread 
				implements MessageGenerator {
	
	private long transmitPeriod;
	
	private Formatter formatter;
	private Transmitter transmitter;
	private NavigationDriver navigation;
	private ArrayList<Averager> averagers;
	
	public DefaultMessageGenrator() {
		Properties prop = Configure.instance();
		try {
			this.formatter = (Formatter)Class.forName(
					prop.getProperty("messageFormat", "org.apple.transmitter.DefaultFormatter"))
					.newInstance();
			this.transmitter = (Transmitter)(Class.forName(
					prop.getProperty("transmitterType", "org.apple.transmitter.DefaultTransmitter"))
					.newInstance());
			if ("true".equals(prop.getProperty("collectPosition"))) {
				this.navigation = (NavigationDriver)(Class.forName(
					prop.getProperty("NavigationDriver", "org.apple.navigation.GpsNavigationDriver"))
					.newInstance());
			}
			else {
				this.navigation = null;
			}
			
			this.averagers = new ArrayList<Averager>();
			
			if ("true".equals(prop.getProperty("collectAirTemperature"))) {
				System.out.println(Class.forName("org.apple.averager.AirTemperatureAverager"));
				averagers.add((Averager)Class.forName("org.apple.averager.AirTemperatureAverager").newInstance());
			}
			if ("true".equals(prop.getProperty("collectSeaTemperature"))) {
				averagers.add((Averager)Class.forName("org.apple.averager.SeaTemperatureAverager").newInstance());
			}
			if ("true".equals(prop.getProperty("collectWindSpeed"))) {
				averagers.add((Averager)Class.forName("org.apple.averager.WindSpeedAverager").newInstance());
			}
			
			transmitPeriod = Integer.parseInt(prop.getProperty("transmitterPeriod"));
		} catch (InstantiationException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		} catch (IllegalAccessException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}
	
	public void init() {
		this.transmitter.init();
	}

	public void startGenerator() {
		this.start();
	}
	
	public void run() {
		while (true) {
			try {
				Thread.sleep(transmitPeriod);
				
				Vector<SensorReading> averages = new Vector<SensorReading> ();
				for (int i = 0; i < this.averagers.size(); i ++) {
					averages.add(this.averagers.get(i).average());
				}
				Position position = null;
				if (navigation != null)
					navigation.getPosition();
				
				String info = this.formatter.format(position, averages);
				
				this.transmitter.send(info);
				
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			
		}
	}

}
